package com.jijuxie.common.service;

import com.jijuxie.common.exception.ServiceException;
import java.io.File;
import java.io.IOException;
import java.util.Arrays;
import java.util.List;
import java.util.UUID;
import org.apache.commons.io.FilenameUtils;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Value;
import org.springframework.stereotype.Service;
import org.springframework.web.multipart.MultipartFile;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.util.unit.DataSize;

/**
 * 文件上传服务
 * 
 * @author jijuxie
 */
@Service
public class FileService {
    
    private static final Logger log = LoggerFactory.getLogger(FileService.class);
    
    /** 上传路径 */
    @Value("${upload.path:D:/jijuxie/upload/}")
    private String uploadPath;
    
    /** 访问URL */
    @Value("${upload.url:/profile/}")
    private String uploadUrl;
    
    /** 头像目录 */
    @Value("${upload.subdirs.avatars:avatars/}")
    private String avatarsDir;
    
    /** 聊天图片目录 */
    @Value("${upload.subdirs.chat:chat/}")
    private String chatDir;
    
    /** 房源图片目录 */
    @Value("${upload.subdirs.house:house/}")
    private String houseDir;
    
    /** 系统图片目录 */
    @Value("${upload.subdirs.sys:system/}")
    private String sysDir;
    
    /** 允许的文件类型 */
    @Value("${upload.allowed-types:jpg,jpeg,png,gif,webp}")
    private String allowedTypes;
    
    /** 最大文件大小(MB) - 使用DataSize自动转换带单位的值 */
    @Value("${upload.max-size:10MB}")
    private DataSize maxFileSize;
    
    /**
     * 上传头像
     * 
     * @param file 文件
     * @return 访问URL
     */
    public String uploadAvatar(MultipartFile file) {
        return upload(file, avatarsDir);
    }
    
    /**
     * 上传头像（带用户ID）
     * 
     * @param file 文件
     * @param userId 用户ID
     * @return 访问URL
     */
    public String uploadAvatar(MultipartFile file, Long userId) {
        validateFile(file);
        
        // 获取文件名
        String originalFilename = file.getOriginalFilename();
        
        // 文件扩展名
        String extension = FilenameUtils.getExtension(originalFilename);
        if (!isAllowedExtension(extension)) {
            throw new ServiceException("上传失败，不支持的文件类型");
        }
        
        // 新文件名 - 用avatar_user_id形式，便于识别
        String fileName = "avatar_" + userId + "_" + System.currentTimeMillis() + "." + extension;
        
        // 目标路径 - 使用avatar目录而不是avatars
        String avatarDirPath = uploadPath + "avatar/";
        File avatarDir = new File(avatarDirPath);
        if (!avatarDir.exists()) {
            avatarDir.mkdirs();
            log.info("创建头像目录: {}", avatarDirPath);
        }
        
        File targetFile = new File(avatarDirPath, fileName);
        log.info("保存头像文件到: {}", targetFile.getAbsolutePath());
        
        try {
            // 保存文件
            file.transferTo(targetFile);
            
            // 返回访问URL
            String avatarUrl = uploadUrl + "avatar/" + fileName;
            log.info("头像访问URL: {}", avatarUrl);
            return avatarUrl;
        } catch (IOException e) {
            log.error("头像保存失败: {}", e.getMessage(), e);
            throw new ServiceException("头像保存失败", e);
        }
    }
    
    /**
     * 上传聊天图片
     * 
     * @param file 文件
     * @return 访问URL
     */
    public String uploadChatImage(MultipartFile file) {
        return upload(file, chatDir);
    }
    
    /**
     * 上传房源图片
     * 
     * @param file 文件
     * @return 访问URL
     */
    public String uploadHouseImage(MultipartFile file) {
        return upload(file, houseDir);
    }
    
    /**
     * 上传系统图片
     * 
     * @param file 文件
     * @return 访问URL
     */
    public String uploadSystemImage(MultipartFile file) {
        return upload(file, sysDir);
    }
    
    /**
     * 上传文件
     * 
     * @param file 文件
     * @param subDir 子目录
     * @return 访问URL
     */
    private String upload(MultipartFile file, String subDir) {
        validateFile(file);
        
        // 获取文件名
        String originalFilename = file.getOriginalFilename();
        
        // 文件扩展名
        String extension = FilenameUtils.getExtension(originalFilename);
        if (!isAllowedExtension(extension)) {
            throw new ServiceException("上传失败，不支持的文件类型");
        }
        
        // 新文件名
        String fileName = UUID.randomUUID().toString().replaceAll("-", "") + "." + extension;
        
        // 目标路径
        String targetDir = uploadPath + subDir;
        File targetFile = new File(targetDir, fileName);
        
        // 确保目录存在
        if (!targetFile.getParentFile().exists()) {
            targetFile.getParentFile().mkdirs();
        }
        
        try {
            // 保存文件
            file.transferTo(targetFile);
            
            // 返回访问URL
            return uploadUrl + subDir + fileName;
        } catch (IOException e) {
            throw new ServiceException("文件保存失败", e);
        }
    }
    
    /**
     * 验证文件
     * 
     * @param file 文件
     */
    private void validateFile(MultipartFile file) {
        if (file == null || file.isEmpty()) {
            throw new ServiceException("上传失败，文件为空");
        }
        
        long size = file.getSize();
        long maxSize = maxFileSize.toBytes(); // 使用DataSize的toBytes()方法获取字节数
        if (size > maxSize) {
            throw new ServiceException("上传失败，文件大小超过限制(" + maxFileSize.toMegabytes() + "MB)");
        }
    }
    
    /**
     * 检查文件类型是否允许
     * 
     * @param extension 扩展名
     * @return 是否允许
     */
    private boolean isAllowedExtension(String extension) {
        if (StringUtils.isEmpty(extension)) {
            return false;
        }
        
        List<String> allowed = Arrays.asList(allowedTypes.split(","));
        return allowed.contains(extension.toLowerCase());
    }
    
    /**
     * 删除文件
     * 
     * @param fileUrl 文件URL
     * @return 是否删除成功
     */
    public boolean deleteFile(String fileUrl) {
        if (fileUrl == null || fileUrl.isEmpty()) {
            return false;
        }
        
        // 移除URL前缀和查询参数
        String filePath = fileUrl.replace(uploadUrl, "");
        if (filePath.contains("?")) {
            filePath = filePath.substring(0, filePath.indexOf("?"));
        }
        
        File file = new File(uploadPath + filePath);
        if (file.exists()) {
            boolean deleted = file.delete();
            log.info("删除文件: {}, 结果: {}", file.getAbsolutePath(), deleted ? "成功" : "失败");
            return deleted;
        }
        
        log.warn("文件不存在: {}", file.getAbsolutePath());
        return false;
    }
    
    /**
     * 上传房源图片到指定子目录
     * 
     * @param file 文件
     * @param subDir 子目录
     * @return 访问URL
     */
    public String saveHouseImage(MultipartFile file, String subDir) {
        validateFile(file);
        
        // 获取文件名
        String originalFilename = file.getOriginalFilename();
        
        // 文件扩展名
        String extension = FilenameUtils.getExtension(originalFilename);
        if (!isAllowedExtension(extension)) {
            throw new ServiceException("上传失败，不支持的文件类型");
        }
        
        // 新文件名
        String fileName = UUID.randomUUID().toString().replaceAll("-", "") + "." + extension;
        
        // 目标路径
        String targetDir = uploadPath + subDir;
        File targetDirFile = new File(targetDir);
        if (!targetDirFile.exists()) {
            targetDirFile.mkdirs();
        }
        
        File targetFile = new File(targetDir, fileName);
        
        try {
            // 保存文件
            file.transferTo(targetFile);
            
            // 返回访问URL
            return uploadUrl + subDir + fileName;
        } catch (IOException e) {
            log.error("房源图片保存失败: {}", e.getMessage(), e);
            throw new ServiceException("文件保存失败", e);
        }
    }
} 